"""
【1】 分为服务端和客户端，要求可以有多个客户端同时操作。
【2】 客户端可以查看服务器文件库中有什么文件。
【3】 客户端可以从文件库中下载文件到本地。
【4】 客户端可以上传一个本地文件到文件库。
【5】 使用print在客户端打印命令输入提示，引导操作
服务端
"""
from socket import *
from threading import Thread
import os
from time import sleep

FTP="/home/tarena/FTP/"

class Handle(Thread):
    def __init__(self,connfd):
        self.connfd=connfd
        super().__init__()

    # 查看
    def do_list(self):
        files=os.listdir(FTP)
        if files:
            self.connfd.send(b"OK")
            sleep(0.1)  #防止OK与后面的内容粘包
            data="\n".join(files)
            self.connfd.send(data.encode())
        else:
            self.connfd.send(b"FAIL")

    # 下载
    def do_get(self,filename):
        try:
            file=open(FTP+filename,"rb")
        except:
            self.connfd.send(b"FAIL")
        else:
            self.connfd.send(b"OK")
            while True:
                data=file.read(1024)
                if not data:
                    break
                self.connfd.send(data)
            sleep(0.1)
            self.connfd.send(b"##")
            file.close()

    #上传
    def do_put(self,filename):
        try:
            file = open(FTP + filename, "wb")
            self.connfd.recv(b"FAIL")
        finally:
            self.connfd.recv(b"OK")
        while True:
            data = file.read(1024)
            if not data:
                break
            self.connfd.send(data)
        file.close()
        self.connfd.send(b"##")

    def run(self):
        while True:
            data = self.connfd.recv(1024).decode()
            tmp=data.split(" ")
            if not data or tmp[0]=="EXIT":
                break
            elif tmp[0]=="LIST":
                self.do_list()
            elif tmp[0]=="RETR":
                self.do_get(tmp[1])
            elif tmp[0]=="STOP":
                self.do_put(tmp[1])
        self.connfd.close()



class FtpServer():
    def __init__(self,*,host="",port=0):
        self.host=host
        self.port=port
        self.address=(host,port)
        self.sock=self._create_socket()

    def _create_socket(self):
        tcp_socket=socket()
        tcp_socket.bind(self.address)
        return tcp_socket

    # 服务启动函数
    def serve_forever(self):
        self.sock.listen(5)
        print("Listen the port %d" %self.port)
        # 循环链接客户端
        while True:
            connfd, addr =self.sock.accept()
            print("Connfd from", addr)
            handle=Handle(connfd)
            handle.start()

if __name__ == '__main__':
    server=FtpServer(host="0.0.0.0",port=8888)
    server.serve_forever()










































































